
#ifndef _IREADER_H_
#define _IREADER_H_

#include <BMap>
#include <BStream>
#include <BNode>
#include <BLight>
#include <BCamera>
#include <BScene>
#include <BMesh>
#include <BGeometry>
#include <BMesh>
#include <BCone>
#include <BCube>
#include <BCylinder>
#include <BSphere>
#include <BTorus>
#include <BSurface>

#include <BImage>
#include <BFont>
#include <BDisplay>
#include <BMaterial>
#include <BTexture>
#include <BProgram>
#include <BShader>
#include <BUniform>

#include <BReadWrite>

#define CHUNK_NODE			10
#define CHUNK_LIGHT			13
#define CHUNK_CAMERA		15
#define CHUNK_MESH			17
#define CHUNK_GEOMETRY		18
#define CHUNK_ELEMENT		19

#define CHUNK_CONE			26
#define CHUNK_CUBE			27
#define CHUNK_CYLINDER		28
#define CHUNK_SPHERE		29
#define CHUNK_TORUS			31
#define CHUNK_SURFACE		33

#define CHUNK_FONT			100
#define CHUNK_PALETTE		102
#define CHUNK_IMAGE			108
#define CHUNK_DISPLAY		109
#define CHUNK_BITMAP		110
#define CHUNK_PIXMAP		112

#define CHUNK_MATERIAL		205
#define CHUNK_MATERIAL_ID	206
#define CHUNK_TEXTURE		207
#define CHUNK_TEXTURE_ID	208
#define CHUNK_PROGRAM		209
#define CHUNK_PROGRAM_ID	210
#define CHUNK_STATE			211
#define CHUNK_STATE_ID		212
#define CHUNK_SHADER		213
#define CHUNK_UNIFORM		214

#define CHUNK_OBJECT_MAX	300

//value
#define CHUNK_NAME			301
#define CHUNK_ENABLE		302
#define CHUNK_VISIBLE		304
#define CHUNK_MATRIX		306
#define CHUNK_RECT			307
#define CHUNK_SPACE			308

#define CHUNK_LIGHTING		310
#define CHUNK_DEPTHTEST		311
#define CHUNK_CULLBACK		312
#define CHUNK_NORMALIZE		313
#define CHUNK_LINESMOOTH	314
#define CHUNK_LINEWIDTH		315
#define CHUNK_POINTSMOOTH	316
#define CHUNK_POINTSIZE		317
#define CHUNK_POLYGONMODE	318

#define CHUNK_COLOR			319
#define CHUNK_COLORMAP		320
#define CHUNK_COLLIDING		322
#define CHUNK_VERTICES		353
#define CHUNK_NORMALS		354
#define CHUNK_TEXCOORDS		355
#define CHUNK_FACES			356
#define CHUNK_AMBIENT		357
#define CHUNK_DIFFUSE		358
#define CHUNK_SPECULAR		359
#define CHUNK_EMISSION		360
#define CHUNK_SHININESS		361
#define CHUNK_ATTENUATION	362
#define CHUNK_ATTENUATION2	363
#define CHUNK_POSITION		364
#define CHUNK_UP			365
#define CHUNK_CENTER		366
#define CHUNK_WIDTH			367
#define CHUNK_NEAR			369
#define CHUNK_FAR			370
#define CHUNK_BACKGROUND	371
#define CHUNK_FILENAME		373
#define CHUNK_FORMAT		374
#define CHUNK_SIZE			375
#define CHUNK_PIXELS		376
#define CHUNK_ORIGIN		399
#define CHUNK_RIGHT			400
#define CHUNK_FRONT			401
#define CHUNK_RIGHTSEGMENT	402
#define CHUNK_FRONTSEGMENT	403
#define CHUNK_BLEND			450
#define CHUNK_FILTER		451
#define CHUNK_WRAP			452
#define CHUNK_BLENDCOLOR	453
#define CHUNK_MIPMAP		454
#define CHUNK_PRIMITIVE		460
#define CHUNK_FIRST			461
#define CHUNK_COUNT			462
#define CHUNK_INDICES		463
#define CHUNK_TYPE			466
#define CHUNK_TEXT			467
#define CHUNK_SIGN			468

#define CHUNK_MAX			500

namespace BWE
{
	class IReadWrite
	{
	public:
		class Chunk
		{
		public:
			Chunk()
			{
				begin = 0;
				sign = 0;
				size = 0;
				end = 0;
			}
			int			begin;
			int			sign;
			int			size;
			int			end;
		};
		class AutoChunk : public Chunk
		{
		public:
			AutoChunk(BStream* stream, int sign)
			{
				this->stream = stream;
				this->sign = sign;
				begin = stream->offset();
				size = 0;
				end = 0;
				stream->wmove(16);
			}
			~AutoChunk()
			{
				end = stream->offset();
				size = end - begin - 16;
				stream->seek(begin);
				stream->write(this, 16);
				stream->seek(end);
			}
			
			BStream*	stream;
		};

	public:
		IReadWrite();
		~IReadWrite();

		virtual bool readObject(const BString& fileName, BObject* object);
		virtual bool writeObject(const BString& fileName, const BObject* object);

	private://read
		bool readNode(BNode* node);
		bool readLight(BLight* light);
		bool readCamera(BCamera* camera);

		bool readMesh(BMesh* mesh);
		bool readGeometry(BGeometry* geometry);
		bool readElement(BElement* element);

		bool readMaterial(BMaterial* material);
		bool readImage(BImage* image);
		bool readDisplay(BDisplay* display);
		bool readState(BState* state);
		bool readProgram(BProgram* program);
		bool readShader(BShader* shader);
		bool readUniform(BUniform* uniform);
		bool readFont(BFont* font);

	protected:
		bool writeSMTP(const BScene* scene, const BNode* node);

		bool writeObjectData(const BObject* object);
		bool writeNodeData(const BNode* node);
		bool writeShapeData(const BShape* shape);
		bool writeTextureData(const BTexture* texture);
		bool writeWidgetData(const BWidget* widget);

		bool writeNode(const BNode* node);
		bool writeLight(const BLight* light);
		bool writeCamera(const BCamera* camera);

		bool writeShape(const BShape* shape);
		bool writeMesh(const BMesh* mesh);
		bool writeGeometry(const BGeometry* geometry);
		bool writeElement(const BElement* element);

		bool writeCube(const BCube* cube);
		bool writeCylinder(const BCylinder* cylinder);
		bool writeSphere(const BSphere* sphere);
		bool writeTorus(const BTorus* torus);

		bool writeState(const BState* state);
		bool writeMaterial(const BMaterial* material);
		bool writeTexture(const BTexture* texture);
		bool writeImage(const BImage* image);
		bool writeDisplay(const BDisplay* display);
		bool writeProgram(const BProgram* program);
		bool writeShader(const BShader* shader);
		bool writeUniform(const BUniform* uniform);
		bool writeFont(const BFont* font);

	private:
		BStream*			stream;

		BArray<BState*>			_states;
		BArray<BMaterial*>		_materials;
		BArray<BTexture*>		_textures;
		BArray<BProgram*>		_programs;
	};
}

#endif